package boerse.main.Gui;

import java.util.Timer;
import java.util.TimerTask;

import boerse.main.Account.AccountManager;
import boerse.main.Exceptions.*;
import javafx.animation.KeyFrame;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * Create main Window with javafx
 * @author Domi
 *
 */
public class MainWindow{

	private AccountManager accountManager;
	private static String player;
	private Stage primaryStage;
	private String sortMode;
	private String sortShare;

	
	
	public MainWindow (AccountManager accountManager, Stage stage) throws Exception  {
		this.accountManager = accountManager;
		primaryStage = stage;
		sortMode = "Date";
		
		
		start();
	}

	
	public void start() throws Exception {

		primaryStage.setTitle("Boersenspiel");
		
		primaryStage.setScene(createStartScene());
		primaryStage.show();
		
	}
	
	/**
	 * Create the first Scene. You must create a Player first to work with the tool
	 * @return the Scene
	 */
	private Scene createStartScene() {
		BorderPane mainWindow = new BorderPane();
		
		MenuBar menuBar = createMenuBar();
		mainWindow.setTop(menuBar);
		
		Scene scene = new Scene(mainWindow, 1000,500);
		return scene;
	}
	
	/**
	 * Create the running Scene. Where the player can work on.
	 * @return
	 */
	private Scene createRunningScene() {
		BorderPane mainWindow= new BorderPane();
		
		GridPane workingPane = new GridPane();
		ColumnConstraints column1 = new ColumnConstraints();
	    column1.setPercentWidth(50);
	    ColumnConstraints column2 = new ColumnConstraints();
	    column2.setPercentWidth(50);
	    workingPane.getColumnConstraints().addAll(column1, column2);
	    	
		MenuBar menubar = createMenuBar();
		GridPane account = createAccountGridPane();
		GridPane createBuySellField = createBuySellField();
		HBox myShares = createMyShares();
		HBox allShare = createExsistingShares();
		VBox transferList = createTransferList();
		
		workingPane.add(account, 0, 0);
		workingPane.add(createBuySellField, 1,0);
		workingPane.add(myShares, 0,1);
		workingPane.add(allShare, 1, 1);
		
		mainWindow.setCenter(workingPane);
		mainWindow.setTop(menubar);
		mainWindow.setBottom(transferList);
		Scene scene = new Scene(mainWindow, 1000, 500);
		
		return scene;
	}
	/**
	 * Create the Menu Bar
	 * @return
	 */
	private MenuBar createMenuBar() {
		MenuBar menuBar = new MenuBar();
		
		Menu file = new Menu("File");
		final MenuItem exitMenu = new MenuItem("Exit");
		exitMenu.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				exit();
			}
			
		});
		
		final Menu newGame = new Menu("Multiplayer");
		final MenuItem newWindow = new MenuItem("new Window");
		newWindow.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				try {
					Stage secoundStage = new Stage();
					secoundStage.setScene(createStartScene());
					MainWindow secoundPlayer = new MainWindow(accountManager, secoundStage);
					secoundPlayer.start();
				} catch (Exception e) {
					e.printStackTrace();
				}

			}
			
		});
		
		newGame.getItems().addAll(newWindow);
		file.getItems().addAll(newGame, exitMenu);
		
		
		Menu account = new Menu("Account");
		
		final MenuItem createPlayer = new MenuItem("create new player");
		createPlayer.setOnAction(new EventHandler<ActionEvent>() {
			
			@Override
			public void handle(ActionEvent event) {
				createPlayerStage();
			}
			
		});
		
		final Menu changePlayer = new Menu("change player");
		
		String players[] = accountManager.getAllPlayer().split("\n");
		for (int i = 0; i < players.length; i++) {
			final MenuItem playerName = new MenuItem(players[i]);
			playerName.setOnAction(new EventHandler<ActionEvent>() {

				@Override
				public void handle(ActionEvent event) {
					player = playerName.getText();
					primaryStage.setScene(createRunningScene());
					primaryStage.show();
				}
				
			});
			changePlayer.getItems().add(playerName);
		}
		
		account.getItems().addAll(createPlayer, changePlayer);
		
		final Menu help = new Menu("Help");
		
		menuBar.getMenus().addAll(file, account, help);
		return menuBar;
	}
	
	/**
	 * Create a new Stage where the user can add a Player and his start cash
	 */
	private void createPlayerStage() {
		final Stage stage = new Stage();
		
		GridPane gridPane = new GridPane();
		gridPane.setVgap(4);
		gridPane.setHgap(2);
		gridPane.setAlignment(Pos.CENTER);
		
		final Label infoLabel = new Label("");
		final Label cash = new Label("Cash:");
		final TextField setCash = new TextField();
		final Label name = new Label("Name:");
		final TextField setName = new TextField();
		
		Button okButton = new Button("OK");
		okButton.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				try {
					player = setName.getText();
					int money = Integer.parseInt(setCash.getText());
					if (money < 0)
						throw new NegativeValueException();
					accountManager.createPlayer(player);
					accountManager.addMoney(player, money);
					primaryStage.setScene(createRunningScene());
					primaryStage.show();
					stage.close();
				} catch(NumberFormatException e) {
					infoLabel.setText("Not a number");
				} catch (NegativeValueException e) {
					infoLabel.setText("No negativ Value");
				} 
			}
			
		});
		
		Button cancelButton = new Button("Cancel");
		cancelButton.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				stage.close();				
			}
			
		});
		
		gridPane.add(name,0,0);
		gridPane.add(setName,0,1);
		gridPane.add(cash, 1,0);
		gridPane.add(setCash, 1,1);
		gridPane.add(okButton, 0,2);
		gridPane.add(cancelButton, 1,2);
		gridPane.add(infoLabel, 0,3);
		
		Scene scene = new Scene(gridPane, 300, 150);
		stage.setTitle("Create Player");

		stage.setScene(scene);
		stage.initModality(Modality.WINDOW_MODAL);
		stage.initOwner(primaryStage.getScene().getWindow());

		stage.show();
	}
	
	/**
	 * Create the Pane with the account informations
	 * @return
	 */
	private GridPane createAccountGridPane() {
		
		GridPane accountInfo = new GridPane();
		accountInfo.setPadding(new Insets(25,25,25,25));
		accountInfo.setHgap(2);
		accountInfo.setVgap(4);
		Label assetName = new Label("Asset");
		Label playerName = new Label(player);
		Label overallName = new Label ("Overall");
		Label overallValue = new Label (((Long) accountManager.getAllAssets(player)).toString());
		Label cashName = new Label("Cash");
		Label cashValue = new Label(((Long) accountManager.getCashAccountPrice(player)).toString());
		Label shareDepositName = new Label("Share Deposit");
		Label shareDepositValue = new Label(((Long) accountManager.getShareDepositPrice(player)).toString());
		accountInfo.add(assetName, 1, 0);
		accountInfo.add(playerName, 0, 0);
		accountInfo.add(overallName, 0 ,1);
		accountInfo.add(overallValue, 1, 1);
		accountInfo.add(cashName, 0, 2);
		accountInfo.add(cashValue, 1, 2);
		accountInfo.add(shareDepositName, 0, 3);
		accountInfo.add(shareDepositValue, 1, 3);
		
		return accountInfo;
		
	}
	
	/**
	 * Create the Pane with the buy and sell options
	 * @return
	 */
	private GridPane createBuySellField() {
		GridPane mainPane = new GridPane();
		mainPane.setPadding(new Insets(25,25,25,25));
		mainPane.setVgap(3);
		mainPane.setHgap(2);
		HBox buttonBox = new HBox();
		HBox textBox = new HBox();
		final Label infoLabel = new Label("");
				
		final TextField shareValue = new TextField("");
		final TextField countValue = new TextField("");
		Label shareName = new Label("Share");
		Label countName = new Label("Quantity");
		textBox.getChildren().addAll(shareName, shareValue, countName, countValue);
		
		Button buyButton = new Button("Buy");
		buyButton.setOnAction(new EventHandler<ActionEvent>(){

			@Override
			public void handle(ActionEvent event) {
				try {
					accountManager.buyShare(player, shareValue.getText(), Integer.parseInt(countValue.getText()));
					infoLabel.setText("Success");
					primaryStage.setScene(createRunningScene());
					primaryStage.show();
				} catch (NumberFormatException e) {
					infoLabel.setText("Qutantity is not a number");
				} catch (NegativeValueException e) {
					infoLabel.setText("Quantity is negativ");
				} catch (NotEnoughMoneyException e) {
					infoLabel.setText("Not enough money");
				}
			}
			
		});
		Button sellButton = new Button("Sell");	
		sellButton.setOnAction(new EventHandler<ActionEvent>(){

			@Override
			public void handle(ActionEvent event) {
				try {
					accountManager.sellShare(player, shareValue.getText(), Integer.parseInt(countValue.getText()));
					infoLabel.setText("Success");
					primaryStage.setScene(createRunningScene());
					primaryStage.show();
				
				} catch (NumberFormatException e) {
					infoLabel.setText("Count is not a number");
				} catch (NegativeValueException e) {
					infoLabel.setText("Count is negativ");
				} catch (NegativeShareCountException e) {
					infoLabel.setText("Not enough share");
				} catch(NoSuchShareException e) {
					infoLabel.setText("No such share");
				}
			}
			
		});
		buttonBox.getChildren().addAll(buyButton, sellButton);
		
		Button useAgentButton = new Button("Use Agent");
		useAgentButton.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				accountManager.useAgent(player);
				
			}
			
		});
		
		mainPane.add(textBox, 0,0);
		mainPane.add(buttonBox, 0,1);
		mainPane.add(infoLabel, 0,2);
		mainPane.add(useAgentButton, 1,0);
		
		return mainPane;
	}
	
	/**
	 * Create the actual Share list from players shares
	 * @return
	 */
	private HBox createMyShares() {		
		HBox hBox = new HBox();
		hBox.setPadding(new Insets(25,25,25,25));
		
		VBox name = new VBox();
		VBox price = new VBox();
		VBox quantity = new VBox();
		VBox buyPrice = new VBox();
		
		name.setPadding(new Insets(10,10,10,10));
		price.setPadding(new Insets(10,10,10,10));
		quantity.setPadding(new Insets(10,10,10,10));
		buyPrice.setPadding(new Insets(10,10,10,10));
		
		Label shareName = new Label("Name");
		Label sharePrice = new Label("Price");
		Label shareQuantity = new Label("Quantity");
		Label shareBuyPrice = new Label("BuyPrice");
		
		name.getChildren().add(shareName);
		price.getChildren().add(sharePrice);
		quantity.getChildren().add(shareQuantity);
		buyPrice.getChildren().add(shareBuyPrice);
		
		String[] shares = accountManager.getShareDeposit(player).split("\n");
		
		for (int i = 0; i < shares.length; i++) {
			if (shares[i].equals("")) {
				break;
			}
			
			name.getChildren().add(new Label(shares[i].split(":")[0]));
			price.getChildren().add(new Label(shares[i].split(":")[1]));
			quantity.getChildren().add(new Label(shares[i].split(":")[2]));
			buyPrice.getChildren().add(new Label(shares[i].split(":")[3]));
		
		}
	
		hBox.getChildren().addAll(name, price, quantity, buyPrice);
	
		return hBox;
	}

	/**
	 * Create the list of the existing shares in the system
	 * @return
	 */
	private HBox createExsistingShares() {
		HBox hBox = new HBox();
		hBox.setPadding(new Insets(25,25,25,25));
		
		VBox name = new VBox();
		VBox price = new VBox();
		
		name.setPadding(new Insets(10,10,10,10));
		price.setPadding(new Insets(10,10,10,10));
		
		Label shareName = new Label("Name");
		Label sharePrice = new Label("Price");
		
		name.getChildren().add(shareName);
		price.getChildren().add(sharePrice);
		
		String[] shares = accountManager.getAllShare().split("\n");
		
		for (int i = 0; i < shares.length; i++) {
			if (shares[i].equals("")) {
				break;
			}
			
			name.getChildren().add(new Label(shares[i].split(":")[0]));
			price.getChildren().add(new Label(shares[i].split(":")[1]));
		
		}
	
		hBox.getChildren().addAll(name, price);
	
		return hBox;
	}
	
	/**
	 * Create the list of the Tranfers
	 * @return
	 */
	private VBox createTransferList() {
		Label head = new Label("Transfer List");
		VBox vBox = new VBox();
		vBox.setPadding(new Insets(25,25,25,25));
		vBox.getChildren().add(head);
		String[] transfers;
		
		if (sortShare == null) { 
			transfers = accountManager.getTransfers(player, sortMode, "CONSOLE").split("\n");
		} else {
			transfers = accountManager.getTransfers(player, sortMode, sortShare, "CONSOLE").split("\n");
		}
		
		for (int i = 0; i < transfers.length; i++) {
			Label label = new Label(transfers[i]);
			vBox.getChildren().add(label);
		}
		
		vBox.setAlignment(Pos.CENTER);
		
		return vBox;
	}
	
	/**
	 * Exit the Programm
	 */
	private void exit() {
		System.exit(0);
	}
	
}


